#pragma once
#include <cassert>
#include <fstream>
#include <memory>
#include <unistd.h>



namespace mylog
{
    namespace Util
    {
        struct JsonData;
    } // namespace Util

    class LogFlush
    {
    public:
        using ptr = std::shared_ptr<LogFlush>;
        LogFlush();
        virtual ~LogFlush() = default;
        virtual void flush(const char* data, size_t len) = 0; // 不同的写文件方式不同

    protected:
        mylog::Util::JsonData* g_conf_data;
    };

    class StdoutFlush : public LogFlush
    {
    public:
        using ptr = std::shared_ptr<StdoutFlush>;
        void flush(const char* data, size_t len) override;
    };

    class FileFlush : public LogFlush
    {
    public:
        using ptr = std::shared_ptr<FileFlush>;
        FileFlush(const std::string& filename);

        void flush(const char* data, size_t len) override;

    private:
        std::string filename_;
        FILE* fs_ = NULL;
    };

    class RollFileFlush : public LogFlush
    {
    public:
        using ptr = std::shared_ptr<RollFileFlush>;
        RollFileFlush(const std::string &filename, size_t max_size);

        void flush(const char *data, size_t len) override;

    private:
        void InitLogFile();

        // 构建落地的滚动日志文件名称
        std::string CreateFilename();

    private:
        size_t cnt_ = 1;
        size_t cur_size_ = 0;
        size_t max_size_;
        std::string basename_;
        // std::ofstream ofs_;
        FILE* fs_ = NULL;
    };

    class LogFlushFactory
    {
    public:
        using ptr = std::shared_ptr<LogFlushFactory>;
        template <typename FlushType, typename... Args>
        static std::shared_ptr<LogFlush> CreateLog(Args &&...args)
        {
            return std::make_shared<FlushType>(std::forward<Args>(args)...);
        }
    };
} // namespace log